/**
 * 公共工具类
 * 作者：xc
 * 版本：1.0.0
 */
export class CommonTool {
    /**
     * 非空返回true
     * 参数： str 效验支付串
     */
    static notNull(str) {
        if (str === undefined) {
            return false;
        } else if (str === null) {
            return false;
        } else if (str === '') {
            return false;
        } else if (typeof str === 'object') {
            if (Object.keys(str).length === 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 给指定字段写入数据
     *
     * 参数： data 数据对象
     * 参数： field 操作的字段(.[index].)代表数组，index数组表
     * 参数： value 要替换的值
     */
    static setObjectField(data, field, value) {
        if (value === undefined || value === null) {
            console.error('传入的value不能为空,检测配置是否正确!');
            return {};
        }
        if (field === undefined || field === null) {
            console.error('传入的field不能为空,检测配置是否正确!');
            return {};
        }
        let str = '';
        let str1 = '';
        const fields = field.split('.');
        for (let i = 0; i < fields.length; i++) {
            const char = fields[i].split('');
            if (char[0] === '[' && char[char.length - 1] === ']') {
                const length = parseFloat(fields[i].split('[')[1].split(']')[0]);
                str = str + '[';
                for (let j = 0; j < length; j++) {
                    if (j !== length) {
                        str = str + '{},';
                    }
                }
                if (i === fields.length - 1) {
                    str = str + JSON.stringify(value) + ']';
                } else {
                    str1 = str1 + ']';
                }
            } else {
                if (i === fields.length - 1) {
                    str = str + '{"' + fields[i] + '":' + JSON.stringify(value);
                    str1 = str1 + '}';
                } else {
                    str = str + '{"' + fields[i] + '":';
                    str1 = str1 + '}';
                }
            }
        }
        const obj = JSON.parse(str + str1.split('').reverse().join(''));
        if (obj instanceof Array) {
            obj.forEach((ref, index) => {
                data[index] = ref;
            });
            return data;
        } else {
            return this.deepMerge(data, obj);
        }

    }

    /**
     * 深度合并对象对像
     * 参数： data
     * 参数： obj
     */
    static deepMerge(data, obj) {
        let key;
        for (key in obj) {
            if (!CommonTool.notNull(obj[key])) {
                continue;
            }
            if (data[key] instanceof Array && obj[key] instanceof Array) {
                for (let i = 0; i < obj[key].length; i++) {
                    if (CommonTool.notNull(data[key][i]) && data[key][i].toString() === '[object Object]') {
                        data[key][i] = this.deepMerge(data[key][i], obj[key][i]);
                    } else {
                        if (JSON.stringify(obj[key][i]) !== '{}') {
                            data[key][i] = obj[key][i];
                        }
                    }
                }
            } else if (data[key] instanceof Array) {
                data[key] = obj[key];
            } else if (CommonTool.notNull(data[key]) && data[key].toString() === '[object Object]') {
                this.deepMerge(data[key], obj[key]);
            } else {
                data[key] = obj[key];
            }
        }
        return data;
    }

    /**
     * 获取指定字段的数据
     * 参数： data 数据
     * 参数： field 数据的那个属性
     */
    static getObjectField(data, field) {
        let obj;
        const fields = field.split('.');
        for (let i = 0; i < fields.length; i++) {
            if (i === 0) {
                obj = data[fields[i]];
            } else {
                if (CommonTool.notNull(obj)) {
                    obj = obj[fields[i]];
                }
            }
        }
        return obj;
    }

    /**
     * 获取指定字段的数据，没有返回空串
     * 参数： data 数据
     * 参数： field 数据的那个属性
     */
    static conversion(data, field) {
        const obj = CommonTool.getObjectField(data, field);
        if (CommonTool.notNull(obj)) {
            return obj;
        } else {
            return '';
        }
    }

    /**
     * 解析url,给url的{}符号替换成合适的数据
     * 参数：url url格式：/user/{userId}/name
     * 参数：data 数据格式：{userId:123456}
     * 返回: url字符串
     */
    static analysisUrl(url, data) {
        const array = Object.getOwnPropertyNames(data);
        array.forEach((key, index) => {
            url = url.replace('{' + key + '}', data[key]);
        });
        return url;
    }

    /**
     * 将data解析成字符串并且拼接url
     * 参数： url url地址
     * 参数：data 参数对象
     * 返回: url字符串
     */
    static analysisParam(url, data) {
        let param = '';
        let array = [];
        if (CommonTool.notNull(data)) {
            array = Object.getOwnPropertyNames(data);
        }
        for (let i = 0; i < array.length; i++) {
            const key = array[i];
            if (i !== 0) {
                if (CommonTool.notNull(data[key])) {
                    param += '&';
                }
            }
            if (CommonTool.notNull(data[key])) {
                param += key + '=' + data[key];
            }
        }
        if (CommonTool.notNull(param)) {
            return url + '?' + param;
        } else {
            return url;
        }
    }

    /**
     * 获取Cookie
     * 参数：key 存入数据的key
     */
    static getCookie(key) {
        const name = key + '=';
        const decodedCookie = decodeURIComponent(document.cookie);
        const ca = decodedCookie.split(';');
        for (let i = 0; i < ca.length; i++) {
            let c = ca[i];
            while (c.charAt(0) === ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) === 0) {
                return c.substring(name.length, c.length);
            }
        }
        return '';
    }

    /**
     * 写入Cookie
     * 参数： key 存入数据的key，必传
     * 参数： value 存入数据的值，必传
     * 参数： expires 有效期，单位毫秒,默认:1800000
     * 参数： path Cookie的路径,默认:/
     * 参数： sameSite SameSite 有两个属性值，分别是 Strict 和 Lax,Strict:表明这个 cookie 在任何情况下都不可能作为第三方 cookie
     */
    static setCookie(key, value, ...params) {
        const expires = params.length > 0 ? params[0] : null;
        const path = params.length > 1 ? params[1] : null;
        const sameSite = params.length > 2 ? params[2] : null;
        let cookie = key + '=' + value + ';';
        if (CommonTool.notNull(expires)) {
            const date = new Date();
            date.setTime(date.getTime() + expires);
            cookie = cookie + 'expires=' + date.toUTCString() + ';';
        }
        if (CommonTool.notNull(path)) {
            cookie = cookie + 'path=' + path + ';';
        }
        if (CommonTool.notNull(sameSite)) {
            cookie = cookie + 'sameSite=' + sameSite + ';';
        }
        document.cookie = cookie;
    }

    /**
     * 删除Cookie
     * 参数： key 数据的key，必传
     * 参数： path Cookie的路径,默认:/
     */
    static deleteCookie(key, ...params) {
        const path = params.length > 0 ? params[0] : null;
        const data = CommonTool.getCookie(key);
        CommonTool.setCookie(key, data, 1, path);
    }

    /**
     * base64字符串转换为Blob对像
     * 参数： base64Data 数据
     * 返回： Blob对象
     */
    static dataURItoBlob(base64Data) {
        let byteString;
        byteString = CommonTool.base64Decode(base64Data);
        const ia = new Uint8Array(byteString.length);
        for (let i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Blob([ia]);
    }

    /**
     * Base64编码
     * 参数： data 编码的数据
     */
    static base64Encode(data) {
        return window.btoa(data);
    }

    /**
     * Base64解码
     * 参数： data base64编码后的数据
     */
    static base64Decode(data) {
        return window.atob(data);
    }

    /**
     * 图片转缩略图
     * 参数： base64Url 图片的base64编码
     * 参数： callback 回调返回缩略图地址
     * 参数： w 宽
     * 参数： h 高
     */
    static compressImage(base64Url, callback, w, h) {
        // 初始化数据
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        w = w || 0;
        h = h || 0;
        const im = new Image();
        im.onload = (e) => {
            let thit = {width: 0, height: 0};
            // @ts-ignore
            thit = e.currentTarget;
            // 为传入缩放尺寸用原尺寸
            if (!w) {
                w = thit.width;
            }
            if (!h) {
                h = thit.height;
            }
            // 以长宽最大值作为最终生成图片的依据
            if (w !== thit.width || h !== thit.height) {
                let ratio;
                if (w > h) {
                    ratio = thit.width / w;
                    h = thit.height / ratio;
                } else if (w === h) {
                    if (thit.width > thit.height) {
                        ratio = thit.width / w;
                        h = thit.height / ratio;
                    } else {
                        ratio = thit.height / h;
                        w = thit.width / ratio;
                    }
                } else {
                    ratio = thit.height / h;
                    w = thit.width / ratio;
                }
            }
            // 以传入的长宽作为最终生成图片的尺寸
            if (w > h) {
                const offset = (w - h) / 2;
                canvas.width = canvas.height = w;
                ctx.drawImage(im, 0, offset, w, h);
            } else if (w < h) {
                const offset = (h - w) / 2;
                canvas.width = canvas.height = h;
                ctx.drawImage(im, offset, 0, w, h);
            } else {
                canvas.width = canvas.height = h;
                ctx.drawImage(im, 0, 0, w, h);
            }
            callback(canvas.toDataURL('image/png'));
        };
        im.src = base64Url;
        return canvas;
    }

    /**
     * 获取后缀
     */
    static getSuffix(name) {
        let suffix = '';
        if (CommonTool.notNull(name)) {
            suffix = name.substring(name.lastIndexOf('.'), name.length);
        }
        return suffix.toLowerCase();
    }


    /**
     * 获取文件空间转换
     */
    static getSpace(value) {
        if (value < 1024) {
            return value + 'b';
        } else if (value < 1048576) {
            return (value / 1024).toFixed(2) + 'kb';
        } else if (value < 1073741824) {
            return (value / 1048576).toFixed(2) + 'mb';
        } else if (value < 1099511627776) {
            return (value / 1073741824).toFixed(2) + 'gb';
        } else if (value < 1.1259e+15) {
            return (value / 1099511627776).toFixed(2) + 'tb';
        } else if (value < 1.1529e+18) {
            return (value / 1.1259e+15).toFixed(2) + 'pb';
        } else {
            return (value / 1.1529e+18).toFixed(2) + 'eb';
        }
    }

    /**
     * 字符串转
     */
    static turnDate(str) {
        return new Date(str.replace(/-/g, '/'));
    }
}
